/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Data.DiagramFactory;

import Data.DiagramFactory.LayoutStrategies.LayoutStrategyInterface;
import java.util.List;
import Data.Diagram.*;
import org.apache.commons.collections.map.MultiValueMap;
import java.util.Iterator;
import Data.*;
import java.util.Collection;

/**
 *
 * @author Sean
 */
public class DiagramFactoryImpl implements DiagramFactoryInterface{

    final int SYSTEM_WIDTH = 300;
    //final int SYSTEM_HEIGHT = 510;
    final int SYSTEM_X = 200;
    final int SYSTEM_Y = 20;
    final int UC_WIDTH = 200;
    final int UC_HEIGHT = 50;
    final int UC_X = 250;
    final int ACTOR_X = 85;
    final int OFFSET_25 = 25;
    final int OFFSET_32 = 32;
    final int OFFSET_70 = 70;
    final int OFFSET_90 = 90;
    final int OFFSET_110 = 110;


    private MultiValueMap systemMap;
    private MultiValueMap actorMap;
    private Diagram Parent;
    private List<UseCaseStruct> useCases;
    private UseCaseStruct tempUseCase;
    private Collection<String> valuesForKey;

    
    private int actY = 60;
    //private int useCaseX;
    private int useCaseY = 60;
    private int sysHeight;



    public DiagramFactoryImpl( ) {
        this.systemMap = new MultiValueMap();
        this.actorMap = new MultiValueMap();
        this.Parent = new Diagram();
        this.useCases = UseCaseModel.getUseCaseVector();       
    }



    @Override
    public DiagramInterface GenerateDiagram(List usecases) {
        //throw new UnsupportedOperationException("Not supported yet.");
        GenerateSystemMap();
        GenerateActorMap();
        GenerateSystems();   
        return(Parent);
    }

    @Override
    public DiagramInterface GenerateDiagram(List usecases, LayoutStrategyInterface Strategy) {
        //throw new UnsupportedOperationException("Not supported yet.");       
        GenerateSystemMap();        
        GenerateActorMap();
        GenerateSystems();
        return(Parent);
    }

    private void GenerateSystemMap(){
        //String msg = "";
        for (Iterator<UseCaseStruct> it = useCases.iterator(); it.hasNext();){
            tempUseCase = it.next();
            if(!systemMap.containsValue(tempUseCase.getVNPhrase())){
                systemMap.put(tempUseCase.getSystem(), tempUseCase.getVNPhrase());
            }          
            //msg = systemMap.entrySet().toString();
            sysHeight = ((systemMap.totalSize())*UC_HEIGHT)+((systemMap.totalSize()+1)*SYSTEM_Y) + SYSTEM_Y;
        }
        //java.lang.System.out.print("sys map: "+ msg +"\n");
    }

    private void GenerateActorMap(){
        //String msg = "";
        for (Iterator<UseCaseStruct> it = useCases.iterator(); it.hasNext();){
            tempUseCase = it.next();
            actorMap.put(tempUseCase.getActor(), tempUseCase.getVNPhrase());
            //msg = actorMap.entrySet().toString();
        }
        //java.lang.System.out.print("\nactor map: " + msg+ "\n");
    }

    private void GenerateSystems(){
       String name;
       for( Iterator<String> it = systemMap.keySet().iterator(); it.hasNext();){
            name = it.next();
            //java.lang.System.out.print("\nsystems being added to diagram: " + next + "\n");
            Parent.add(new Data.Diagram.System(name, SYSTEM_X, SYSTEM_Y, SYSTEM_WIDTH, sysHeight));
            valuesForKey = systemMap.getCollection(name);
            GenerateUseCases();
            useCaseY = 60;
            GenerateActors();
       }
    }

    private void GenerateActors(){
       String name;
       for( Iterator<String> it = actorMap.keySet().iterator(); it.hasNext();){
            name = it.next();
            //java.lang.System.out.print("\n actors being added to diagram: " + next + "\n");
            Parent.add(new Actor(name, ACTOR_X, actY));
            //actY = actY+OFFSET_32;
            //valuesForKey = actorMap.getCollection(name);
            //GenerateUseCases();
            valuesForKey = actorMap.getCollection(name);
            for( Iterator<String> it2 = systemMap.values().iterator(); it2.hasNext();){
                if(valuesForKey.contains(it2.next())){
                    actY = actY+OFFSET_32;
                    useCaseY = useCaseY+OFFSET_25;
                    GenerateConectors();
                    actY = actY-OFFSET_32;
                    useCaseY = useCaseY+OFFSET_70;
                }
                else{
                    useCaseY = useCaseY+OFFSET_70;
                }
            }
            useCaseY = 60;
            actY = actY+OFFSET_110;
            
       }
    }

    private void GenerateUseCases(){
       String phrase;
       for( Iterator<String> it = valuesForKey.iterator(); it.hasNext();){
            phrase = it.next();
            //java.lang.System.out.print("\nuse cases being added to diagram: " + phrase + "\n");
            Parent.add(new Data.Diagram.UseCase(phrase, UC_X, useCaseY, UC_WIDTH, UC_HEIGHT));
            //useCaseY = useCaseY+OFFSET_25;
            //GenerateConectors();
            useCaseY = useCaseY+OFFSET_70;
       }

       //actY = actY-OFFSET_32;
    }
    
    private void GenerateConectors(){
        Parent.add(new Connector(ACTOR_X+OFFSET_25, actY, UC_X, useCaseY));
        useCaseY = useCaseY-OFFSET_25;
    }


}
